#include "crc16.h"

#define uint16_t uint16_t
//-----------------------------------------------------------------------------
#define CCITT (0x1021)

//-----------------------------------------------------------------------------
static uint16_t _crc(uint32_t n)
{
    uint32_t i, acc;

    for (n <<= 8, acc = 0, i = 8; i > 0; i--, n <<= 1)
    {
        acc = ((n ^ acc) & 0x8000) ? ((acc << 1) ^ CCITT) : (acc << 1);
    }

    return (uint16_t)(acc);
}

//-----------------------------------------------------------------------------
uint16_t CRC16(uint32_t crc, uint8_t *buffer, uint32_t length)
{
    uint32_t i, j;

    for (i = 0; i < length; i++)
    {
        j = (crc >> 8) ^ buffer[i];
        crc = (crc << 8) ^ _crc(j);
    }

    return crc;
}
uint16_t MODBUS_CRC16(uint8_t *buffer, uint16_t length)
{
    uint8_t i;
    //	uint16_t temp=0;
    unsigned short crc = 0xFFFF;
    uint8_t *target_buf;
    target_buf = buffer + 2;
    if (length == 0)
    {
        length = 1;
    }
    while (length--)
    {
        crc ^= *target_buf;
        for (i = 0; i < 8; i++)
        {
            if (crc & 1)
            {
                crc >>= 1;
                crc ^= 0xA001;
            }
            else
            {
                crc >>= 1;
            }
        }
        target_buf++;
    }
    //	temp = crc << 8;
    //	crc = temp + (crc >>8);

    return (crc);
}

uint16_t crc16(uint8_t *buffer, uint16_t length)
{
    uint8_t i;
    uint16_t crc = 0xFFFF;
    uint8_t *target_buf;
    target_buf = buffer;
    if (length == 0)
    {
        length = 1;
    }
    while (length--)
    {
        crc ^= *target_buf;
        for (i = 0; i < 8; i++)
        {
            if (crc & 1)
            {
                crc >>= 1;
                crc ^= 0xA001;
            }
            else
            {
                crc >>= 1;
            }
        }
        target_buf++;
    }
    return (crc);
}